package com.ruoyi.combat.config;

import cn.hutool.json.JSONUtil;
import com.ruoyi.combat.domain.CombatAtlasNewTask;
import com.ruoyi.combat.domain.neo4j.IpNode;
import com.ruoyi.combat.domain.neo4j.IpcNode;
import com.ruoyi.combat.mapper.CombatAtlasTaskMapper;
import com.ruoyi.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.neo4j.driver.Record;
import org.neo4j.driver.Result;
import org.neo4j.driver.types.Node;
import org.neo4j.driver.types.Relationship;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class PredictAntiHomingInfoTask implements Runnable {
    private CombatAtlasTaskMapper combatAtlasTaskMapper;
    private Neo4jConfig neo4jConfig;
    private String ip;
    private CombatAtlasNewTask task;

    public PredictAntiHomingInfoTask(String ip, CombatAtlasNewTask task,CombatAtlasTaskMapper combatAtlasTaskMapper, Neo4jConfig neo4jConfig) {
        this.ip = ip;
        this.task = task;
        this.combatAtlasTaskMapper = combatAtlasTaskMapper;
        this.neo4jConfig = neo4jConfig;
    }


    @Override
    public void run() {
        for (int i = 0; i < 6; i++) {
            String result = getResult(ip, "2");
            System.out.println(i);
            if(StringUtils.isNotEmpty( result)){
                task.setAfter(result);
                combatAtlasTaskMapper.updateCombatAtlasTask( task);
                break;
            }else{
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                   log.error("error",e);
                }
            }
        }
    }

    public String getResult(String ip, String type) {
//        String cql = "MATCH (start_ip:Ip {Ip: '" + ip + "'})-[:BELONGS_TO]->(ipc:IpC) MATCH (ipc)<-[:BELONGS_TO]-(landmark_ip:Ip) WHERE landmark_ip.landmark_node = 1 MATCH path = (landmark_ip)<-[*1..3]-(o:Org) RETURN start_ip, ipc, landmark_ip, o,[node IN nodes(path) | node] as all_nodes_in_path, [rel IN relationships(path) | rel] as all_relationships_in_path, length(path) as path_length";
        String cql = "MATCH (n)-[r]->(m) RETURN n,r,m";
//        String cql = "MATCH (start_ip:Ip {Ip: '" + ip + "'}) MATCH path = (start_ip)-[:BELONGS_TO*1..3]->(o:Org) RETURN start_ip, o, [node IN nodes(path) | node] as all_nodes_in_path, [rel IN relationships(path) | rel] as all_relationships_in_path, length(path) as path_length";
        Result run = neo4jConfig.run(cql, type);
        List<Record> list = run.list();
        List<Map> listdata = new ArrayList<>();
        list.forEach(record -> {
            List<String> keys = record.keys();
            Map<String, Object> data = new HashMap<>();
            keys.forEach(key -> {
                if ("n".equals(key)) {
                    org.neo4j.driver.Value value = record.get(key);
                    Map map = new HashMap();
                    map.put("id", value.asNode().id());
                    map.put("labels", value.asNode().labels());
                    map.put("value", value.asNode().asMap());
                    data.put(key, map);
                } else if ("r".equals(key)) {
                    Relationship relationship = record.get(key).asRelationship();
                    Map map = new HashMap();
                    map.put("type", relationship.type());
                    map.put("start", relationship.startNodeId());
                    map.put("end", relationship.endNodeId());
                    map.put("value", relationship.asMap());
                    map.put("id", relationship.id());
                    data.put(key, map);
                } else if ("m".equals(key)) {
                    org.neo4j.driver.Value value = record.get(key);
                    Map map = new HashMap();
                    map.put("id", value.asNode().id());
                    map.put("labels", value.asNode().labels());
                    map.put("value", value.asNode().asMap());
                    data.put(key, map);
                }
            });
            listdata.add(data);
        });
        return JSONUtil.toJsonStr(listdata);
    }

    public static void main(String[] args) {
        for (int i = 0; i < 6; i++) {
            String result = "";
            System.out.println(i);
            if(StringUtils.isNotEmpty( result)){
                break;
            }else{
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    log.error("error",e);
                }
            }
        }
    }
}
